package com.sky.task;

import com.alibaba.fastjson.JSON;
import com.sky.mapper.user.OrderMapper;
import com.sky.pojo.Orders;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.exception.ServiceException;
import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.payments.nativepay.NativePayService;
import com.wechat.pay.java.service.payments.nativepay.model.QueryOrderByOutTradeNoRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;

@Component
@Slf4j
public class OrderStatusCheckTask {

    private  static final String CANCLE_RESON_OVER_TIME = "超时未支付";
    private  static final String CANCLE_RESON_ORDER_NOT_FOUND = "订单不存在";

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private Config config;

    @Autowired
    private OrderMapper orderMapper;

    @Scheduled(cron = "0 0/1 * * * ?")
    public void orderCheck(){
        //为定时任务加分布式锁
        redisTemplate.opsForValue().setIfAbsent("orderCheck","lock", Duration.ofMinutes(1));
        String lock = (String) redisTemplate.opsForValue().get("orderCheck");
        if (!StringUtils.hasText(lock)){
            log.info("为获取到锁,不执行");
            return;
        }
        log.info("定时检查订单任务开始执行");
        long start = System.currentTimeMillis();
        LocalDateTime time = LocalDateTime.now().minusMinutes(15);
        List<Orders> overTimeOrders = orderMapper.getOverTimeOrders(time);
        for (Orders overTimeOrder : overTimeOrders) {
            String status = payStatusCheck(overTimeOrder.getNumber());
            if (status.equals("success")){
                //用户支付成功,修改订单状态
                log.info("用户支付成功,修改订单支付状态");
                overTimeOrder.setStatus(Orders.TO_BE_CONFIRMED);
                overTimeOrder.setCheckoutTime(LocalDateTime.now());
                overTimeOrder.setPayStatus(Orders.PAID);
            }else if (status.equals("404")){
                log.info("订单不存在");
                overTimeOrder.setStatus(Orders.CANCELLED_ORDER);
                overTimeOrder.setCancelTime(LocalDateTime.now());
                overTimeOrder.setCancelReason(CANCLE_RESON_ORDER_NOT_FOUND);
            }else {
                //用户未支付
                log.info("超时未支付,取消取消订单");
                overTimeOrder.setStatus(Orders.CANCELLED_ORDER);
                overTimeOrder.setCancelTime(LocalDateTime.now());
                overTimeOrder.setCancelReason(CANCLE_RESON_OVER_TIME);
            }
            orderMapper.modifyOrderStatus(overTimeOrder);
        }
        long end = System.currentTimeMillis();
        log.info("定时检查订单状态任务结束,耗时:{}秒",(start-end)/1000);
    }

    /**
     * 查询用户的支付状态
     */
    private String payStatusCheck(String orderNo){
        QueryOrderByOutTradeNoRequest orderByOutTradeNoRequest = new QueryOrderByOutTradeNoRequest();
        orderByOutTradeNoRequest.setMchid("1561414331");
        orderByOutTradeNoRequest.setOutTradeNo(orderNo);

        // 构建service
        NativePayService service = new NativePayService.Builder().config(config).build();

        try {
            Transaction result = service.queryOrderByOutTradeNo(orderByOutTradeNoRequest);
            if (result.getTradeState() .equals(Transaction.TradeStateEnum.SUCCESS)){
                return "success";
            }
        } catch (ServiceException e) {
            // API返回失败, 例如ORDER_NOT_EXISTS
            log.info("订单不存在",e);
            String errorCode = e.getErrorCode();
            return errorCode;
        }
        return "failed";
    }
}
